package tinking.java.operator;

import java.util.Random;

/**
 * @author GaoFeng
 * @date 2019/12/25 16:19
 */
public class BitManipulation {

    public static void main(String[] args) {
        // Random rand = new Random(System.currentTimeMillis());
        Random rand = new Random(47);

        int i = rand.nextInt();
        int j = rand.nextInt();
        printBinaryInt("-1", 1);
        printBinaryInt("+1", +1);

        int maxpos = 2147483647;
        printBinaryInt("maxpos", maxpos);
        int maxneg = -2147483648;
        printBinaryInt("maxneg", maxneg);

        printBinaryInt("i", i);
        printBinaryInt("~i", ~i);
        printBinaryInt("-i", -i);
        printBinaryInt("j", j);
        printBinaryInt("i & j", i & j);
        printBinaryInt("i | j", i | j);
        printBinaryInt("i ^ j", i ^ j);
        printBinaryInt("i << 5", i << 5);
        printBinaryInt("i >> 5", i >> 5);
        printBinaryInt("(~i) >> 5", ~i >> 5);
        printBinaryInt("i >>> 5", i >>> 5);
        printBinaryInt("(~i) >>> 5", ~i >>> 5);

        long l = rand.nextLong();
        long m = rand.nextLong();

        printBinaryLong("-1L", -1L);
        printBinaryLong("+1L", +1L);

        long ll = 9223372036854775807L;
        printBinaryLong("maxpos", ll);
        long lln = -9223372036854775808L;
        printBinaryLong("minneg", lln);

        printBinaryLong("l", l);
        // (0 - 原数) - 1
        printBinaryLong("~l", ~l);
        // 如果是正数，那就变成负数
        printBinaryLong("-l", -l);

        // 打印m
        printBinaryLong("m", m);

        // 取两个数的都为1的位，a & b, 如果一个数是正数，如果a可由b和其他数进行组合，那么会返回b的值;
        printBinaryLong("l & m", l & m);
        // 取两个数其中一个数为1的位，统计两个数为1的位
        printBinaryLong("l | m", l | m);
        // 取两个数都不相等的位，统计两个数不相等的位
        printBinaryLong("l ^ m", l ^ m);
        // l * 2 的 n 次方
        printBinaryLong("l << 5", l << 5);
        // l / 2 的 n 次方，按原数的符号来设置移出来的位，比如水果的
        printBinaryLong("l >> 5", l >> 5);
        // -(a + 1) >> 5
        printBinaryLong("(~l) >> 5", ~l >> 5);
        // l / 2 的 n 次方, 腾出的位用0补充
        printBinaryLong("l >>> 5", l >>> 5);
        // -(a + 1) >>> 5
        printBinaryLong("(~l) >>> 5", ~l >>> 5);
        // 8是否可以和其他数组成10
        printBinaryLong("10 & 8", -4L & 8);

        // 对于无符号右移，无论原数是多少，都用零填充

    }

    private int abs() {
        return 0;
    }

    static void printBinaryInt(String s, int i) {
        // js和Java
        System.out.println(s + " , int: " + i + ", binary:  " + Integer.toBinaryString(i));
    }

    static void printBinaryLong(String s, Long l) {
        // js和script
        System.out.println(s + " , long: " + l + ", binary:  " + Long.toBinaryString(l));
    }

}
